操作 Spring Data JPA 需要對於資料表之間的關聯與配置有一定的了解,可以幫助你在規劃資料庫及撈取資料上有很大的幫助。
後續文章會依序介紹常見的幾種關聯操作,若這邊設計一個情境開設一個電商平台,賣電玩的商品,會有一些表紀錄商品的一些資訊,我們可以藉此來探討資料表之間的關聯。主要有下面這幾張表:

關聯時必須知道誰是父實體(或稱維護方,具有 FK 可以關聯被維護 PK),誰是子實體(被維護、被參考對象)
| 父實體(維護方) | 子實體(被維護方) | |
|---|---|---|
| 關聯 | 具有FK | 被關聯 PK 或其他 | 
| 註解應用區別 | @JoinColumn() | 關聯註解加入參數mappedBy | 
級聯配置參數,針對父實體的資料操作,子實體會有對應自動操作
資料讀取配置參數,設定讀取的方式是立即或是特定條件才讀
各類關聯註解預設值參考
| Relation | Default | 
|---|---|
| @OneToOne | FetchType.EAGER | 
| @ManyToOne | FetchType.EAGER | 
| @OneToMany | FetchType.LAZY | 
| @ManyToMany | FetchType.LAZY | 
一對一的關聯可以從 products 和 product_details 這兩張表之間的關聯看到,一個商品會對應一個詳細資料,要透過 JPA 會用到 @OneToOne 註解來進行關聯,這些關聯註解都有一些參數可以設置。在這邊的範例就是 products 是父實體,product_details 是子實體。
定義父實體 products
@Entity
@Data
@Table(name = "products")
//@JsonIgnoreProperties({"productDetail"}) // 避免循環引用
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Double price;
    private String description;
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "product_detail_id", referencedColumnName = "id")
    private ProductDetails productDetails;
}
@JoinColumn 的 name 參數指的是要提供 FK 的欄位名稱,referencedColumnName 是指被關聯方的 關聯欄位(不寫預設是被關聯的主鍵PK)
定義子實體 product_details
@Entity
@Data
@Table(name = "product_details")
@JsonIgnoreProperties("product")
public class ProductDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String developer;
    private String publisher;
    private String releaseDate;
    private String languageSupport;
    @OneToOne(mappedBy = "productDetails")
    private Product product;
}
這邊需要注意如果需要雙向關聯,這邊也要在關聯要呈現的屬性上面加上 @OneToOne(mappedBy = "{父方映射關聯的欄位}"),這邊也就是指父實體放 @OneToOne 欄位的變數名 productDetails
另外補充如果雙向關聯開啟,就會出現無限循環關聯的問題,你可以想像會出現 product 關聯出 product_details 但裡面又關聯回 product 就會一直永無止境導致回傳資料混亂,有幾個方法可以解決:
實際撈回來的資料
[
    {
        "id": 1,
        "name": "最後生還者",
        "price": 59.99,
        "description": "由 Naughty Dog 開發的動作冒險遊戲。",
        "productDetails": {
            "id": 1,
            "developer": "Naughty Dog",
            "publisher": "Sony Interactive Entertainment",
            "releaseDate": "2013-06-14",
            "languageSupport": "English, Japanese, Chinese"
        }
    },
    {
        "id": 2,
        "name": "巫師3",
        "price": 49.99,
        "description": "由 CD Projekt Red 開發的開放世界角色扮演遊戲。",
        "productDetails": {
            "id": 2,
            "developer": "CD Projekt Red",
            "publisher": "CD Projekt",
            "releaseDate": "2015-05-19",
            "languageSupport": "English, Chinese, Polish"
        }
    },
    // 略......
]
以上就是基本一對一的關聯操作,下篇會來介紹一對多 (1 : N) 的操作模式。
這邊想要補充一下推薦有使用 Intellij 的 database UI ,連接好資料庫之後,對資料庫點右鍵選 Diagrams > Show Diagram 他就可以將各欄位之間的關聯狀況畫出來,還可以匯出圖片,就可以不用自己畫 ER 圖了,真的太強大 !!
Ref:
相關文章也會同步更新我的部落格,有興趣也可以在裡面找其他的技術分享跟資訊。